package ngram_reader.viewer.query;

import math.mathExtended.MathExtended;
import ngram_reader.viewer.query.NoStatSearchQuery.Match;
import ngram_reader.viewer.query.StatisticsSearchQuery.Aggregate;

/**
 *
 * @author g1wshimu
 * Created: Nov 15, 2013
 */
public class SearchQueryFactory {

    private static void validateInput(String query, Match match, int startGram, int endGram) {
        // Make sure the query String is not empty
        if (query.isEmpty()) {
            throw new IllegalArgumentException("Search word/phrase is empty!");
        }

        // If exact match is selected, make sure that the number 
        // of words in the query String is less than or equal to
        // the n-grams selected (otherwise the search will yield no
        // results)
        final int queryWords;
        if (match == Match.EXACT && !MathExtended.bounded((queryWords = query.split("\\s").length),
                startGram, endGram)) {
            throw new IllegalArgumentException(
                    String.format("Search word/phrase has %d words, but you want an exact match from %d to %d n-grams."
                    + " The search will not yield any result!", queryWords, startGram, endGram));
        }
    }

    public static NGramSearchQuery getAllStatSearchQuery(String query, Match match,
            String startGram, String endGram, boolean matchCase) {
        int intStartGram = Integer.parseInt(startGram);
        int intEndGram = Integer.parseInt(endGram);
        validateInput(query, match, intStartGram, intEndGram);

        System.out.println("Using all stat query");

        return new AllStatSearchQuery(query, match, intStartGram, intEndGram, matchCase);
    }

    public static NGramSearchQuery getNoStatSearchQuery(String query, Match match,
            String startGram, String endGram, boolean matchCase) {
        int intStartGram = Integer.parseInt(startGram);
        int intEndGram = Integer.parseInt(endGram);

        validateInput(query, match, intStartGram, intEndGram);

        System.out.println("Using no stat query");

        return new NoStatSearchQuery(query, match, intStartGram, intEndGram, matchCase);
    }

    public static NGramSearchQuery getSearchQuery(String query, Match match,
            String startGram, String endGram, boolean matchCase,
            int startYear, int endYear, int startMatch, int endMatch,
            int startVolume, int endVolume,
            Aggregate aggregateMatch, Aggregate aggregateVolume, boolean ignoreStatistics) {

        int intStartGram = Integer.parseInt(startGram);
        int intEndGram = Integer.parseInt(endGram);

        validateInput(query, match, intStartGram, intEndGram);

        if (ignoreStatistics) {
            System.out.println("Using no stat query");
            return new NoStatSearchQuery(query, match, intStartGram, intEndGram, matchCase);

        } else {
            if ((startYear == Integer.MIN_VALUE) && (endYear == Integer.MAX_VALUE)
                    && (startMatch == Integer.MIN_VALUE) && (endMatch == Integer.MAX_VALUE)
                    && (startVolume == Integer.MIN_VALUE) && (endVolume == Integer.MAX_VALUE)) {
                System.out.println("Using all stat query");
                return new AllStatSearchQuery(query, match, intStartGram, intEndGram, matchCase);
                
            } else {
                System.out.println("Using regular stat query");

                return new StatisticsSearchQuery(query, match,
                        intStartGram, intEndGram, matchCase, startYear, endYear,
                        startMatch, endMatch, startVolume, endVolume,
                        aggregateMatch, aggregateVolume);
            }
        }

    }
}
